home *** CD-ROM | disk | FTP | other *** search
/ Gigarom 1 / Gigarom Macintosh Archives (Quantum Leap)(CDRM1080320)(1993).iso / FILES / APP / E-L / IQ_Test.cpt / IQ Test ƒ / IQ Test Sorce Code ƒ / DoTest.c next >
C/C++ Source or Header  |  1993-02-17  |  7KB  |  277 lines

  1. #include "IQ Test.h"
  2.  
  3. #define CANCEL_ITEM        -1
  4.  
  5.  
  6. static GrafPtr            sBombPictOffscreenPort,
  7.                         sButtonPictOffscreenPort;
  8.  
  9. static pascal void         DrawDlogPictProc(
  10.                             DialogPtr            theDialog,
  11.                             short                itemNumber );
  12. static pascal Boolean     FilterProc(
  13.                             DialogPtr            theDialog,
  14.                             EventRecord            *theEvent,
  15.                             short                *itemHit );
  16. static GrafPtr            MakeOffScreenPort(
  17.                             const Rect            *portRectPtr );
  18.  
  19. void DoTest()
  20.     {
  21.     short            itemHit,
  22.                     itemType;
  23.     Boolean            dialogDone = FALSE;
  24.     DialogPtr        theDialog;
  25.     Handle            itemHandle;
  26.     Rect            itemRect;
  27.     PicHandle        bombPict,
  28.                     buttonPict;
  29.  
  30.     theDialog = GetNewDialog( BOMB_DLOG_ID, NIL_PTR, MOVE_TO_FRONT );
  31.     CenterAsAlert( theDialog );
  32.  
  33.     /*
  34.         Set up the offscreen port containing the dialog bomb picture.
  35.     */
  36.  
  37.     GetDItem( theDialog, BOMB_PICT_USER_ITEM, &itemType, &itemHandle, &itemRect );
  38.     sBombPictOffscreenPort = MakeOffScreenPort( &itemRect );
  39.     if ( sBombPictOffscreenPort == NIL_PTR )
  40.         return;
  41.     bombPict = GetPicture( BOMB_PICT_ID );
  42.     SetPort( sBombPictOffscreenPort );
  43.     DrawPicture( bombPict, &itemRect );
  44.     ReleaseResource( ( Handle ) bombPict );
  45.  
  46.     /*
  47.         Set up the offscreen port containing the button picture.
  48.     */
  49.  
  50.     GetDItem( theDialog, BUTTON_PICT_USER_ITEM, &itemType, &itemHandle, &itemRect );
  51.     sButtonPictOffscreenPort = MakeOffScreenPort( &itemRect );
  52.     if ( sButtonPictOffscreenPort == NIL_PTR )
  53.         return;
  54.     buttonPict = GetPicture( BUTTON_PICT_ID );
  55.     SetPort( sButtonPictOffscreenPort );
  56.     DrawPicture( buttonPict, &itemRect );
  57.     ReleaseResource( ( Handle ) buttonPict );
  58.  
  59.     /*
  60.         Set up the drawing procedure for window updates.
  61.     */
  62.  
  63.     SetPort( theDialog );
  64.     GetDItem( theDialog, BOMB_PICT_USER_ITEM, &itemType, &itemHandle, &itemRect );
  65.     SetDItem( theDialog, BOMB_PICT_USER_ITEM, itemType, ( Handle ) DrawDlogPictProc, &itemRect );
  66.  
  67.     /*
  68.         Do the dialog.
  69.     */
  70.  
  71.     ShowWindow( theDialog );
  72.     while ( dialogDone == FALSE )
  73.         {
  74.         ModalDialog( FilterProc, &itemHit );
  75.         switch( itemHit )
  76.             {
  77.             case CANCEL_ITEM:
  78.                 dialogDone = TRUE;
  79.                 break;
  80.             }
  81.         }
  82.  
  83.     /*
  84.         Clean up by disposing memory allocated in this routine.
  85.     */
  86.  
  87.     ClosePort( sBombPictOffscreenPort );
  88.     DisposePtr( ( *sBombPictOffscreenPort ).portBits.baseAddr );
  89.     DisposePtr( ( Ptr ) sBombPictOffscreenPort );
  90.  
  91.     ClosePort( sButtonPictOffscreenPort );
  92.     DisposePtr( ( *sButtonPictOffscreenPort ).portBits.baseAddr );
  93.     DisposePtr( ( Ptr ) sButtonPictOffscreenPort );
  94.  
  95.     DisposeDialog( theDialog );
  96.     }
  97.  
  98.  
  99. static pascal Boolean FilterProc(
  100.     DialogPtr            theDialog,
  101.     EventRecord            *theEvent,
  102.     short                *itemHit )
  103.     {
  104.     unsigned char        charCode;
  105.     short                itemHeight,
  106.                         itemType,
  107.                         itemWidth,
  108.                         maxLeft,
  109.                         maxTop,
  110.                         newLeft,
  111.                         newTop,
  112.                         portHeight,
  113.                         portWidth;
  114.     Handle                itemHandle;
  115.     Point                mouseLoc;
  116.     Rect                bombRect,
  117.                         itemRect,
  118.                         newRect,
  119.                         testRect;
  120.         
  121.     switch ( ( *theEvent ).what )
  122.         {
  123.         case nullEvent:
  124.             /*
  125.                 Check the mouse position.  If it is near the button image, move the button image.
  126.             */
  127.             
  128.             mouseLoc = ( *theEvent ).where;
  129.             SetPort( theDialog );
  130.             GlobalToLocal( &mouseLoc );
  131.             GetDItem( theDialog, BUTTON_PICT_USER_ITEM, &itemType, &itemHandle, &itemRect );
  132.             testRect = itemRect;
  133.             InsetRect( &testRect, -10, -10 );
  134.             if ( PtInRect( mouseLoc, &testRect ) )
  135.                 {
  136.                 do
  137.                     {
  138.                     GetDItem( theDialog, BOMB_PICT_USER_ITEM, &itemType, &itemHandle, &bombRect );
  139.                     InsetRect( &bombRect, 3, 3 );
  140.                     portWidth = bombRect.right - bombRect.left;
  141.                     portHeight =  bombRect.bottom - bombRect.top;
  142.                     itemHeight = itemRect.bottom - itemRect.top;
  143.                     itemWidth = itemRect.right - itemRect.left;
  144.                     maxTop = portHeight - itemHeight;
  145.                     maxLeft = portWidth - itemWidth;
  146.  
  147.                     do
  148.                         newLeft = Random();
  149.                     while ( newLeft < 0 );
  150.                     newRect.left = bombRect.left + ( newLeft % maxLeft );
  151.                     newRect.right = newRect.left + itemWidth;
  152.  
  153.                     do
  154.                         newTop = Random();
  155.                     while ( newTop < 0 );
  156.                     newRect.top = bombRect.top + ( newTop % maxTop );
  157.                     newRect.bottom = newRect.top + itemHeight;
  158.  
  159.                     testRect = newRect;
  160.                     InsetRect( &testRect, -10, -10 );
  161.                     }
  162.                 while ( PtInRect( mouseLoc, &testRect ) );
  163.                 GetDItem( theDialog, BUTTON_PICT_USER_ITEM, &itemType, &itemHandle, &itemRect );
  164.                 SetDItem( theDialog, BUTTON_PICT_USER_ITEM, itemType, itemHandle, &newRect );
  165.                 
  166.                 DrawDlogPictProc( theDialog, BOMB_PICT_USER_ITEM );
  167.                 }
  168.             *itemHit = 0;
  169.             return FALSE;
  170.             break;
  171.         case keyDown:
  172.             /*
  173.                 A command-period signifies things are over.
  174.             */
  175.             charCode = ( *theEvent ).message & charCodeMask;
  176.             if ( ( charCode == '.' ) && ( ( *theEvent ).modifiers & cmdKey ) )
  177.                 {
  178.                 *itemHit = CANCEL_ITEM;
  179.                 return TRUE;
  180.                 }
  181.             else
  182.                 return FALSE;
  183.             break;
  184.         case mouseDown:
  185.             /*
  186.                 Mimic a real system bomb by intercepting all mouseDown events to avoid beep sound
  187.                     when clicking outside the dialog’s window.
  188.                 itemHit is set to 0, a non-existent item.
  189.             */
  190.             *itemHit = 0;
  191.             return TRUE;
  192.             break;
  193.         default:
  194.             return FALSE;
  195.             break;
  196.         }
  197.     }
  198.  
  199.  
  200. static pascal void DrawDlogPictProc(
  201.     DialogPtr        theDialog,
  202.     short            itemNumber )
  203.     {
  204.     short            itemType;
  205.     Handle            itemHandle;
  206.     Rect            itemRect;
  207.  
  208.     /*
  209.         Update the drawing of the dialog by copying the images from the two offscreen
  210.             ports.  The first offscreen port contains all of the dialog image except
  211.             the “button”; the second offscreen port contains the “button”.  Two images
  212.             are necessary since the location of the “button” changes.
  213.     */
  214.  
  215.     GetDItem( theDialog, BOMB_PICT_USER_ITEM, &itemType, &itemHandle, &itemRect );
  216.     CopyBits(
  217.         &( *sBombPictOffscreenPort ).portBits,
  218.         &( *theDialog ).portBits,
  219.         &( *sBombPictOffscreenPort ).portRect,
  220.         &itemRect,
  221.         srcCopy,
  222.         0L );
  223.     GetDItem( theDialog, BUTTON_PICT_USER_ITEM, &itemType, &itemHandle, &itemRect );
  224.     CopyBits(
  225.         &( *sButtonPictOffscreenPort ).portBits,
  226.         &( *theDialog ).portBits,
  227.         &( *sButtonPictOffscreenPort ).portRect,
  228.         &itemRect,
  229.         srcCopy,
  230.         0L );
  231.     }
  232.  
  233.  
  234. GrafPtr MakeOffScreenPort(
  235.     const Rect        *portRectPtr )
  236.     {
  237.     GrafPtr            newOffscreenPort,
  238.                     oldPort;
  239.  
  240.     /*
  241.         Given a Rect which indicates the size and coordinates of the offscreen port,
  242.             create an offscreen port.
  243.         Return NIL_PTR if there was insufficient memory to create the offscreen port.
  244.     */
  245.  
  246.     GetPort( &oldPort );
  247.     newOffscreenPort = ( GrafPtr ) NewPtr( sizeof( GrafPort ) );
  248.     if ( newOffscreenPort != NIL_PTR )
  249.         {
  250.         OpenPort( newOffscreenPort );
  251.         ( *newOffscreenPort ).portRect = *portRectPtr;
  252.         ( *newOffscreenPort ).portBits.bounds = *portRectPtr;
  253.         RectRgn( ( *newOffscreenPort ).clipRgn, portRectPtr );
  254.         RectRgn( ( *newOffscreenPort ).visRgn, portRectPtr );
  255.         ( *newOffscreenPort ).portBits.rowBytes =
  256.             ( ( ( *portRectPtr ).right - ( *portRectPtr ).left + 15 ) >> 4 ) << 1;
  257.         ( *newOffscreenPort ).portBits.baseAddr =
  258.             NewPtr( ( long ) ( *newOffscreenPort ).portBits.rowBytes *
  259.             ( ( *portRectPtr ).bottom - ( *portRectPtr ).top ) );
  260.         if ( ( *newOffscreenPort ).portBits.baseAddr == NIL_PTR )
  261.             {
  262.             ClosePort( newOffscreenPort );
  263.             DisposPtr( ( Ptr ) newOffscreenPort );
  264.             newOffscreenPort = NIL_PTR;
  265.             }
  266.         else
  267.             {
  268.             SetPort( newOffscreenPort );
  269.             EraseRect( &( *newOffscreenPort ).portRect );
  270.             }
  271.         }
  272.     SetPort( oldPort );
  273.     return ( newOffscreenPort );
  274.     }
  275.  
  276.  
  277.